Micron Document
Fox's Git Mirrors

Node / rns-mirrors / Reticulum-Go.git / files / docs / en / development-and-testing.md

Displaying Rendered • View rawDownload

docs/en/development-and-testing.md 201d27032fbc0af2fd0a560de603cd8786ee75b5 (201d2703) Text, 18.21 KB

Development and testing

Development environment

Requirements:

• Go 1.26.5 or later
• Make or Task
• revive linter for T383838make lint
• Python 3 for crossref vector generation (optional)

Clone the repository. Dependencies are in T383838vendor/. No network fetch is needed for ordinary builds.

Code quality commands

T282828
make fmt
make vet
make lint
make test-short
make vulncheck
make check

T383838make check runs fmt, vet, lint, test-short, and vulncheck in sequence.

Linting

revive with project config:

T282828
revive -config revive.toml -formatter friendly ./pkg/* ./cmd/* ./internal/*

Race detector

T282828
make test-race

Transport and interface packages include dedicated race and deadlock regression tests (T383838interface_stress_race_test.go, T383838pipe_race_test.go, T383838pipe_deadlock_test.go).

Coverage

T282828
make coverage

Opens HTML coverage from T383838coverage.out.

Benchmarks

T282828
make bench
task test-bench-gate

Loopback link throughput smoke (RNS Speedtest-style liveness floor):

T282828
task test-link-speed
reticulum-go speedtest

Nightly T383838sim-heavy also runs T383838test-link-speed.

Project layout for contributors

┌────────────────────┬────────────────────────────────┐
│ Path │ Purpose │
├────────────────────┼────────────────────────────────┤
│ T383838pkg/ │ Public library code │
│ T383838cmd/ │ Binaries and e2e tests │
│ T383838internal/ │ Daemon-only code │
│ T383838tests/crossref/ │ Python vector parity │
│ T383838tests/interop/ │ Live Go/Python tests │
│ T383838scripts/ci/ │ CI install and release scripts │
│ T383838.github/workflows/ │ GitHub Actions │
└────────────────────┴────────────────────────────────┘

Follow existing naming, error wrapping, and SPDX headers in each file.

Testing layers

┌────────────┬───────────────────────────────────────────────────────────┬─────────────────────────┐
│ Layer │ How to run │ What it covers │
├────────────┼───────────────────────────────────────────────────────────┼─────────────────────────┤
│ Unit │ T383838task test / T383838task test-short │ Package T383838*_test.go
│ Property │ T383838task test-property │ T383838*_pbt_test.go and embe… │
│ Mutation │ T383838task test-mutation │ gomutant on cryptograp… │
│ Chaos │ T383838task test-chaos / T383838task test-soak / T383838task test-soak-protect │ T383838TestSimChaos* / T383838TestLi… │
│ Oracle │ T383838task test-oracle │ Crossref vectors, heal… │
│ Smoke │ T383838task test-binary-smoke, binding smokes │ Binary T383838--version/T383838--hel… │
│ Acceptance │ T383838task test-acceptance │ librns SCAFFOLD minimu… │
│ E2E │ T383838task test-e2e │ Daemon reload, UDP pat… │
│ Black box │ T383838task test-blackbox │ CLI T383838Main / T383838rgodump sur… │
│ Interop │ T383838RUN_LIVE_INTEROP=1 go test ./tests/interop/... │ Live Go↔Python (option… │
└────────────┴───────────────────────────────────────────────────────────┴─────────────────────────┘

Unit tests

Standard T383838go test in each package. Run all:

T282828
go test -v ./...

Short mode skips long tests:

T282828
go test -short -v ./...

Property-based tests

Files named T383838*_pbt_test.go use T383838quad4/pbt for generative testing (cryptography, packet, buffer, rate, resource, announce, link, identity). Some properties still live beside unit tests in the same package.

T282828
task test-property

Mutation tests

In-repo T383838tools/gomutant flips same-width operators and re-runs package tests.

T282828
task test-mutation

Default packages: cryptography, packet, announce, destination, identity, ifac, backbone. Override with T383838MUTATION_PACKAGES / T383838MUTATION_THRESHOLD.

Fuzz tests

Files named T383838*_fuzz_test.go cover packet, link, ifac, blackhole, discovery, health counters (T383838pkg/health), pipe HDLC framing (T383838pkg/interfaces/pipe_fuzz_test.go), and librns (T383838pkg/librns).

Chaos and fault injection

Seeded loss, reorder, corruption, and flap tests across layers:

┌─────────────────┬────────────────┬───────────────────────────────────────────────────────────────┐
│ Prefix │ Package │ Focus │
├─────────────────┼────────────────┼───────────────────────────────────────────────────────────────┤
│ T383838TestSimChaos* │ T383838pkg/transport │ Multi-node path and announce under delay/loss/corrupt/reorde… │
│ T383838TestLinkChaos* │ T383838pkg/link │ Establish, packet under loss/reorder, resource under capped … │
│ T383838TestIfaceChaos* │ T383838pkg/interfaces │ TCP HDLC corrupt/reorder, Local corrupt resync, Pipe respawn… │
└─────────────────┴────────────────┴───────────────────────────────────────────────────────────────┘

T282828
task test-chaos
task test-soak
task test-soak-protect

Chaos suites are in-process Go only (sim pipes / HDLC fixtures). Live Go↔Python loss, reorder, and mid-session flap are not covered yet. Healthy-path cross-stack coverage lives under T383838tests/interop/ (T383838RUN_LIVE_INTEROP=1).

dos_protection tests

T383838pkg/protect and interface hooks cover false positives, false negatives, auto learn/persist/relearn, and live sockets.

┌───────────────────────────────┬────────────────────────────────────────────────────────────┬─────┐
│ Suite │ Location │ Fo… │
├───────────────────────────────┼────────────────────────────────────────────────────────────┼─────┤
│ Unit / FP-FN │ T383838pkg/protect/false_positive_test.go │ Qu… │
│ Snapshot / bitrate / priority │ T383838pkg/protect/snapshot_test.go, T383838bitrate_test.go, T383838packetclas… │ St… │
│ Transport handler shed │ T383838pkg/transport/protect_test.go │ Se… │
│ Slow findings │ T383838pkg/rnsutil/slow_protect_test.go │ T383838do… │
│ Sandbox soft-fail │ T383838pkg/sandbox/warn_test.go │ Ra… │
│ Replay traces │ T383838pkg/protect/replay_trace_test.go │ Me… │
│ Property / fuzz │ T383838pkg/protect/property_test.go, T383838fuzz_test.go │ De… │
│ Soak │ T383838task test-soak-protect │ Bo… │
│ Live UDP/TCP │ T383838pkg/interfaces/protect_*_live_test.go │ Re… │
│ Live interop │ T383838tests/interop/dos_protect_live_test.go │ T383838RU… │
└───────────────────────────────┴────────────────────────────────────────────────────────────┴─────┘

T282828
go test ./pkg/protect -short
go test ./pkg/interfaces -run 'LiveUDP|LiveTCP|Protect'
task test-soak-protect
RUN_LIVE_INTEROP=1 go test ./tests/interop -run 'DoSProtect|DoSProtection'

FreeBSD, OpenBSD, and Haiku CI jobs run T383838go test -short ./pkg/protect/ and transport protect tests in addition to T383838pkg/sandbox and self-check. The T383838test-extra soak matrix runs T383838task test-soak-protect.

Config and threat scope: Configuration, Security.

Test oracles

┌────────────────────────────────┬───────────────────────────────────────────────────┐
│ Oracle │ Location │
├────────────────────────────────┼───────────────────────────────────────────────────┤
│ Python crossref vectors │ T383838tests/crossref/
│ Health counter deltas │ T383838pkg/health.TransportOracle / T383838OracleSnapshot.Delta
│ Handshake / adversarial frames │ T383838pkg/packet/testdata/
│ IFAC goldens │ T383838pkg/ifac unit tests │
│ Sim path/hop asserts │ T383838pkg/transport/sim_assertions_test.go
└────────────────────────────────┴───────────────────────────────────────────────────┘

T282828
task test-oracle

Smoke, acceptance, e2e, black box

T282828
task test-binary-smoke
task test-acceptance
task test-e2e
task test-blackbox

Notable additions: T383838pkg/cli dump smoke via T383838Main, T383838pkg/librns.TestAcceptanceScaffoldMinimum, T383838pkg/node.TestUDPPathE2E.

Crossref tests

Location: T383838tests/crossref/

Purpose: byte-level parity with Python reference output.

Workflow:

T282828
./tests/crossref/run_crossref.sh generate # requires Python reference
./tests/crossref/run_crossref.sh test
./tests/crossref/run_crossref.sh all

Vectors are JSON with format version 5 (T383838generate_vectors.py). The reference tree is fetched via rngit in T383838run_crossref.sh.

Coverage includes identity, HKDF, HMAC, packet wire, announces, encryption, links, resources, channel envelopes, buffers, path requests.

Handshake decode trees for porters also live in T383838pkg/packet/testdata/handshake_vectors.json (see packet-debug.md).

Packet debug tools

• Wireshark Lua dissector: T383838tools/wireshark/rns.lua
• T383838reticulum-go dump / rgodump for hex and pcap
• T383838reticulum-go snapshot / rgosnap for path and health JSON
• Timeline convention: interop-timeline.md

T282828
go test ./pkg/packet/ -run 'TestHandshakeVector|TestTshark|TestDecode|TestPCAP'
go test ./pkg/health/ -run TestDrop
go test ./pkg/cli/ -run TestRunDump

Interop tests

Location: T383838tests/interop/

Live tests pair a Go process with Python helpers under T383838tests/interop/py/. HDLC burst (T383838TestLiveInteropHDLCBurst*) and Unpack hop-gate (T383838TestLiveInteropUnpackOracleMatchesPython) cover stream coalescing and refuse-invalid parity.

Enable:

T282828
RUN_LIVE_INTEROP=1 go test -v ./tests/interop/...

Optional Python interpreter (prefer a venv with T383838rns==1.4.2):

T282828
sh scripts/ci/setup-venv-pip.sh 'rns==1.4.2'
PYTHON_INTEROP=.venv/bin/python RUN_LIVE_INTEROP=1 go test -v ./tests/interop/...

Debug harness

NomadNet relay, pageserver, and shared helpers use T383838tests/interop/harness/.

┌───────────────────────┬───────────────────────────────────────────────────────────────┐
│ Variable │ Behavior │
├───────────────────────┼───────────────────────────────────────────────────────────────┤
│ T383838INTEROP_ARTIFACTS=1 │ Always keep artifact dirs (default: only when the test fails) │
│ T383838INTEROP_EVENTS=1 │ Force event logging (also on when artifacts are enabled) │
│ T383838INTEROP_ARTIFACT_ROOT │ Parent directory for durable artifact folders │
└───────────────────────┴───────────────────────────────────────────────────────────────┘

On failure (or with T383838INTEROP_ARTIFACTS=1) the test logs the artifact path and the last events. Typical files:

┌──────────────┬──────────────────────────────────────────────────────────────────┐
│ File │ Contents │
├──────────────┼──────────────────────────────────────────────────────────────────┤
│ T383838events.jsonl │ One JSON object per line (ts, src, event, kind, detail) │
│ T383838stderr.txt │ Captured Python stderr (human RNS logs plus T383838INTEROP_EVENT lines) │
│ T383838env.json │ Selected interop env keys │
└──────────────┴──────────────────────────────────────────────────────────────────┘

Python peers emit T383838INTEROP_EVENT {...} on stderr via T383838tests/interop/py/interop_events.py. Stdout tokens such as T383838READY and T383838REQUEST_OK are unchanged.

Example:

T282828
INTEROP_ARTIFACTS=1 INTEROP_ARTIFACT_ROOT=/tmp/rns-interop \\
RUN_LIVE_INTEROP=1 go test -v ./tests/interop/ -run 'TestLiveNomadNetLinkThroughGoRelay|TestLiveInteropPythonPageServerLargePageRequest'

┌─────────────────────────────────┬────────────────────────────────────────────────────────────────┐
│ Test file │ Topic │
├─────────────────────────────────┼────────────────────────────────────────────────────────────────┤
│ T383838link_live_test.go │ Link sessions, resources, binary burst echo, Go→Python request │
│ T383838channel_buffer_live_test.go │ Channel messages and buffer streams │
│ T383838rncp_blackhole_live_test.go │ rncp file transfer and blackhole LINKIDENTIFY │
│ T383838auto_live_test.go │ AutoInterface │
│ T383838ifac_live_test.go │ IFAC │
│ T383838transport_path_live_test.go │ Path requests │
│ T383838transport_relay_live_test.go │ Transport relay │
│ T383838backbone_live_test.go │ Backbone │
│ T383838quic_live_test.go │ QUIC Go-Go echo (no Python peer) │
│ T383838pipe_live_test.go │ PipeInterface with Python echo │
│ T383838modem73_live_test.go │ Modem73Interface (fake KISS/control, optional modem73 binary … │
│ T383838sdr_live_test.go │ SDRInterface mock exchange (T383838RUN_LIVE_SDR=1) │
│ T383838shared_rpc_live_test.go │ Shared-instance RPC (TCP and Unix on Linux) │
│ T383838pageserver_live_test.go │ Pageserver example │
│ T383838nomadnet_crawl_live_test.go │ Nomadnet crawl │
│ T383838nomadnet_relay_live_test.go │ NomadNet through Go mesh relay │
│ T383838path_cp_live_test.go │ path and rgocp utilities │
│ T383838i2p_live_test.go │ I2PInterface Go and Python (needs SAM) │
│ T383838directory_outgoing_live_test.go │ Public directory clearnet TCP peers │
└─────────────────────────────────┴────────────────────────────────────────────────────────────────┘

Package-specific live tests

┌─────────────────────────────┬──────────────────────────────────────────────────────────────┐
│ Package │ Env var │
├─────────────────────────────┼──────────────────────────────────────────────────────────────┤
│ T383838pkg/i2p, T383838pkg/interfaces I2P │ T383838RUN_LIVE_I2P=1 (optional T383838I2P_SAM_ADDRESS, T383838I2P_DIRECTORY_URL) │
│ T383838pkg/blackhole │ T383838RUN_PY_INTEROP=1
│ T383838pkg/discovery │ T383838RUN_PY_INTEROP=1
└─────────────────────────────┴──────────────────────────────────────────────────────────────┘

End-to-end daemon tests

T383838cmd/reticulum-go/ contains T383838controlapi_e2e_test.go, T383838reload_e2e_test.go, and related tests.

Host self-check

T383838reticulum-go self-check is a host OS preflight. It validates that platform features work on the machine under test (crypto, identity file backend, sandbox, securemem, loopback interfaces, daemon with sandbox, shared-instance RPC, and on Unix a SIGHUP config/interface reload).

T282828
make test-self-check
# or
task test-self-check
# or
./bin/reticulum-go self-check --json --full

Flags:

┌───────────────┬──────────────────────────────────────────────────────────────────────┐
│ Flag │ Behavior │
├───────────────┼──────────────────────────────────────────────────────────────────────┤
│ T383838--json │ Machine-readable report │
│ T383838--quick │ Core and platform only (no loopback or daemon) │
│ T383838--full │ Also probe QUIC, HTTPS, VSOCK, Pipe, and Serial │
│ T383838--interop │ Optional external tools (crossref vectors, Python RNS, binding CLIs) │
│ T383838--strict │ Treat warnings as failures │
│ T383838--binary PATH │ Binary used for CLI and daemon checks │
└───────────────┴──────────────────────────────────────────────────────────────────────┘

Environment:

┌────────────────────────────────┬────────────────────────────────────────────────────────┐
│ Variable │ Behavior │
├────────────────────────────────┼────────────────────────────────────────────────────────┤
│ T383838RETICULUM_SELF_CHECK=1 │ Used by CI wrappers that invoke the same checklist │
│ T383838RETICULUM_SELF_CHECK_INTEROP=1 │ Enables the interop tier │
│ T383838RETICULUM_TEST_KEYRING=1 │ Require Linux keyring round-trip (fail if unavailable) │
└────────────────────────────────┴────────────────────────────────────────────────────────┘

Exit code is non-zero on any fail result. With T383838--strict, warnings also fail.

Daemon checks include Control API health with sandbox enabled, shared-instance GetInterfaceStats RPC, and (except Windows and FreeBSD CapEnter) SIGHUP reload of a UDP interface.

CI runs self-check on Linux (amd64 and arm64), macOS, Windows, FreeBSD, and OpenBSD. Extra Linux arches (T383838386, arm GOARM=6, riscv64, ppc64le, ppc64) run via T383838qemu-user-static (T383838task test-self-check-386, T383838test-self-check-arm, T383838test-self-check-riscv64, T383838test-self-check-ppc64le, T383838test-self-check-ppc64). Android emulator self-check is a separate workflow (T383838selfcheck-android.yml) on schedule or workflow_dispatch.

NetBSD is not in CI. Run T383838reticulum-go self-check manually on that host.

Vendoring

Ordinary builds use vendored modules. Refresh after dependency changes:

T282828
task vendor-sync

Requires T383838LIBS_ROOT pointing at the Reticulum-Go-Projects sibling tree for replace directives. Commit T383838go.mod, T383838go.sum, and T383838vendor/ after refresh.

Day-to-day clones only need T383838vendor/ to build offline.

CI overview

GitHub Actions workflows in T383838.github/workflows/:

┌───────────────────────┬──────────────────────────────────────────────────────────────────────────┐
│ Workflow │ Role │
├───────────────────────┼──────────────────────────────────────────────────────────────────────────┤
│ ci.yml │ Build, test, reproducibility, OS self-check (Linux amd64/arm64 plus 386… │
│ selfcheck-android.yml │ Android emulator self-check (nightly / manual) │
│ security.yml │ Gosec, govulncheck, Trivy, SBOM dispatch │
│ codeql.yml │ CodeQL for Go, JS/TS, Python, and Actions workflows │
│ dependency-review.yml │ PR dependency and advisory gate │
│ publish.yml │ Tagged releases, cosign attestations │
└───────────────────────┴──────────────────────────────────────────────────────────────────────────┘

CI uses Go 1.26.5 via T383838actions/setup-go in T383838.github/actions/setup-ci with T383838GOTOOLCHAIN=local and vendored modules. Actions are SHA-pinned. Dependabot opens weekly PRs for Action bumps (T383838.github/dependabot.yml).

Cross-compilation

T282828
make build-linux
make build-windows
make build-darwin
make build-all

Legacy Windows uses go-legacy-win7 (T383838make build-windows-legacy).

WebAssembly development

T282828
task build-wasm
task test-wasm

Requires Task. See Embedding and WebAssembly.

librns shared library

T282828
task build-librns
make -C bindings/c/examples/smoke
./bindings/c/examples/smoke/librns-smoke

Needs a C toolchain and CGO. Daemon builds stay T383838CGO_ENABLED=0. See librns.

Odin bindings

T282828
task build-librns
task test-odin

Requires the Odin compiler on T383838PATH (CI installs a pinned monthly release via T383838scripts/ci/setup-odin.sh, job T383838Odin bindings). Package lives under T383838bindings/odin. See librns.

Zig bindings

T282828
task build-librns
task test-zig

Requires Zig 0.16.0 or later on T383838PATH (CI installs a pinned release via T383838scripts/ci/setup-zig.sh, job T383838Zig bindings). Package lives under T383838bindings/zig. See librns.

C++ bindings

T282828
task build-librns
task test-cpp

Requires CMake and a C++17 compiler on T383838PATH (CI job T383838C++ bindings). Package lives under T383838bindings/cpp. See librns.

Dart bindings

T282828
task build-librns
task test-dart

Requires the Dart SDK on T383838PATH (CI pins T3838383.11.4, job T383838Dart bindings) and CGO for T383838librns.so FFI smoke tests. Package and examples live under T383838bindings/dart. See librns Dart FFI and Control API.

Rust bindings

T282828
task build-librns
task test-rust

Requires T383838cargo on T383838PATH (CI job T383838Rust bindings). Package and examples live under T383838bindings/rust.

Python bindings

T282828
task build-librns
task test-python

Requires T383838python3 on T383838PATH (CI job T383838Python bindings). Package and examples live under T383838bindings/python.

Lua bindings

T282828
task build-librns
task test-lua

Requires LuaJIT on T383838PATH (CI job T383838Lua bindings). Package and examples live under T383838bindings/lua.

Swift bindings

T282828
task build-librns
task test-swift

Requires T383838swift on T383838PATH (CI pins T3838386.0.3 via T383838scripts/ci/setup-swift.sh, job T383838Swift bindings). Package and examples live under T383838bindings/swift.

Java bindings

T282828
task build-librns
task test-java

Requires T383838javac on T383838PATH (CI uses Temurin 17, job T383838Java bindings). Package and examples live under T383838bindings/java. JNA is fetched on first build.

Kotlin bindings

T282828
task build-librns
task test-kotlin

Requires T383838kotlinc and T383838javac on T383838PATH (CI pins Kotlin T3838382.1.10 via T383838scripts/ci/setup-kotlin.sh, job T383838Kotlin bindings). Package and examples live under T383838bindings/kotlin and depend on T383838bindings/java.

C ABI examples

T282828
task build-librns
task test-c

Builds and runs T383838bindings/c/examples (smoke plus page-fetch/pageserver compile). Binding CI jobs also run T383838make -C bindings/<lang> examples.

Adding a change safely

1. Write or extend unit tests in the affected package
2. If wire format changes, update crossref vectors and Python reference together
3. Run T383838make check locally
4. For protocol behavior, add or extend interop test when feasible
5. Update Compatibility and COMPATIBILITY.md if parity status changes

Related documents

Security for CI scan detail

Served by rngit 1.5.2 - Generated in 0.04s